/**
 * TypingIndicatorFrames - 正在输入指示器动画帧组件
 *
 * 功能特性：
 * - 3 个圆点依次闪烁的动画
 * - 4 帧动画：点1亮 → 点2亮 → 点3亮 → 全暗
 * - 可自定义颜色、大小、间距
 * - 轻量级，无依赖
 *
 * 使用方式：
 * ```tsx
 * <FrameAnimationController frameCount={4} playing={true}>
 *   {(frame) => <TypingIndicatorFrames currentFrame={frame} />}
 * </FrameAnimationController>
 * ```
 */

import React from 'react';
import { View, StyleSheet, ViewStyle } from 'react-native';

// ==================== 类型定义 ====================

export interface TypingIndicatorFramesProps {
  /** 当前帧索引（0-3） */
  currentFrame: number;

  /** 圆点颜色，默认 '#999999' */
  color?: string;

  /** 圆点大小（直径），默认 8 */
  dotSize?: number;

  /** 圆点之间的间距，默认 6 */
  gap?: number;

  /** 亮起时的透明度，默认 1.0 */
  activeOpacity?: number;

  /** 暗淡时的透明度，默认 0.3 */
  inactiveOpacity?: number;

  /** 容器样式 */
  style?: ViewStyle;
}

// ==================== 帧数据定义 ====================

/**
 * 4 帧数据：每一帧包含 3 个圆点的透明度（0-1）
 * 帧0: 点1亮
 * 帧1: 点2亮
 * 帧2: 点3亮
 * 帧3: 全暗（形成呼吸效果）
 */
const FRAME_DATA = [
  [1, 0.3, 0.3], // 帧 0: 点1高亮
  [0.3, 1, 0.3], // 帧 1: 点2高亮
  [0.3, 0.3, 1], // 帧 2: 点3高亮
  [0.3, 0.3, 0.3], // 帧 3: 全部暗淡
];

// ==================== 组件实现 ====================

export const TypingIndicatorFrames: React.FC<TypingIndicatorFramesProps> = ({
  currentFrame,
  color = '#999999',
  dotSize = 8,
  gap = 6,
  activeOpacity = 1.0,
  inactiveOpacity = 0.3,
  style,
}) => {
  // 确保 currentFrame 在有效范围内
  const safeFrame = Math.max(0, Math.min(currentFrame, FRAME_DATA.length - 1));
  const opacities = FRAME_DATA[safeFrame];

  // 映射透明度值（从 0-1 到 inactiveOpacity-activeOpacity）
  const mappedOpacities = opacities.map(opacity => inactiveOpacity + opacity * (activeOpacity - inactiveOpacity));

  return (
    <View style={[styles.container, { gap }, style]}>
      {mappedOpacities.map((opacity, index) => (
        <View
          key={index}
          style={[
            styles.dot,
            {
              width: dotSize,
              height: dotSize,
              borderRadius: dotSize / 2,
              backgroundColor: color,
              opacity: opacity,
            },
          ]}
        />
      ))}
    </View>
  );
};

// ==================== 样式 ====================

const styles = StyleSheet.create({
  container: {
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'center',
  },
  dot: {
    // 基础样式，具体尺寸通过 props 动态设置
  },
});

// ==================== 便捷封装组件 ====================

/**
 * TypingAnimation - 开箱即用的正在输入动画
 *
 * 这是一个便捷封装，内部组合了 FrameAnimationController 和 TypingIndicatorFrames
 *
 * @example
 * ```tsx
 * <TypingAnimation
 *   playing={isTyping}
 *   color="#999"
 *   size="medium"
 * />
 * ```
 */

import { FrameAnimationController } from '../FrameAnimationController';

export interface TypingAnimationProps {
  /** 是否播放 */
  playing?: boolean;

  /** 颜色 */
  color?: string;

  /** 预设尺寸 */
  size?: 'small' | 'medium' | 'large';

  /** 自定义尺寸（会覆盖 size 预设） */
  dotSize?: number;
  gap?: number;

  /** 每帧持续时间（毫秒），默认 300 */
  frameDuration?: number;

  /** 是否启用平滑过渡，默认 false */
  smoothTransition?: boolean;

  /** 亮起时的透明度，默认 1.0 */
  activeOpacity?: number;

  /** 暗淡时的透明度，默认 0.3 */
  inactiveOpacity?: number;

  /** 容器样式 */
  style?: ViewStyle;
}

// 预设尺寸配置
const SIZE_PRESETS = {
  small: { dotSize: 6, gap: 4 },
  medium: { dotSize: 8, gap: 6 },
  large: { dotSize: 10, gap: 8 },
};

export const TypingAnimation: React.FC<TypingAnimationProps> = ({
  playing = false,
  color,
  size = 'medium',
  dotSize,
  gap,
  frameDuration = 300,
  smoothTransition = false,
  activeOpacity,
  inactiveOpacity,
  style,
}) => {
  // 合并尺寸配置
  const sizeConfig = SIZE_PRESETS[size];
  const finalDotSize = dotSize ?? sizeConfig.dotSize;
  const finalGap = gap ?? sizeConfig.gap;

  return (
    <FrameAnimationController
      frameCount={4}
      frameDuration={frameDuration}
      autoPlay={playing}
      loop={true}
      smoothTransition={smoothTransition}
    >
      {frameIndex => (
        <TypingIndicatorFrames
          currentFrame={frameIndex}
          color={color}
          dotSize={finalDotSize}
          gap={finalGap}
          activeOpacity={activeOpacity}
          inactiveOpacity={inactiveOpacity}
          style={style}
        />
      )}
    </FrameAnimationController>
  );
};
